<script setup lang="ts">
import { ref, onMounted, nextTick, onBeforeUnmount, watch } from "vue";
import * as echarts from "echarts";
import { useAppStore } from "@/store/modules/app";
import { useDark } from "@pureadmin/utils";

const props = defineProps({
  // 图表类型：bar, line, pie, radar, scatter, etc.
  type: {
    type: String,
    default: "bar"
  },
  // 图表标题
  title: {
    type: String,
    default: ""
  },
  // 图表数据
  data: {
    type: Object,
    required: true
  },
  // 图表容器高度
  height: {
    type: String,
    default: "350px"
  },
  // 图表容器宽度
  width: {
    type: String,
    default: "100%"
  },
  // 图表主题
  theme: {
    type: String,
    default: ""
  },
  // 是否显示加载中
  loading: {
    type: Boolean,
    default: false
  },
  // 自定义选项
  option: {
    type: Object,
    default: () => ({})
  }
});

const emit = defineEmits(["chartCreated"]);

const appStore = useAppStore();
const { isDark } = useDark();
const chartRef = ref<HTMLDivElement | null>(null);
const chartInstance = ref<echarts.ECharts | null>(null);

// 初始化图表
const initChart = async () => {
  if (!chartRef.value) return;

  // 等待DOM更新
  await nextTick();

  // 销毁旧实例
  if (chartInstance.value) {
    chartInstance.value.dispose();
  }

  // 创建新实例
  chartInstance.value = echarts.init(chartRef.value, props.theme);

  // 设置图表选项
  updateChart();

  // 监听窗口大小变化
  window.addEventListener("resize", handleResize);

  // 发送创建完成事件
  emit("chartCreated", chartInstance.value);
};

// 处理窗口大小变化
const handleResize = () => {
  if (chartInstance.value) {
    chartInstance.value.resize();
  }
};

// 更新图表
const updateChart = () => {
  if (!chartInstance.value) return;

  try {
    // 确保数据存在
    if (!props.data) {
      console.error("图表数据为空");
      return;
    }

    // 确保series是数组
    const seriesData = Array.isArray(props.data.series)
      ? props.data.series
      : [];

    // 确保每个系列都有type属性并且系列对象存在
    const validSeries = seriesData
      .filter(series => series !== undefined && series !== null)
      .map(series => {
        // 如果系列没有type属性，使用props.type作为默认值
        if (!series.type) {
          return { ...series, type: props.type };
        }
        return series;
      });

    // 根据图表类型设置不同的配置
    const baseOption = {
      title: {
        text: props.title,
        left: "center"
      },
      tooltip: {
        trigger: props.type === "pie" ? "item" : "axis",
        axisPointer: {
          type: "shadow"
        }
      },
      grid: {
        left: "3%",
        right: "4%",
        bottom: "3%",
        containLabel: true
      },
      legend: {
        top: props.title ? 30 : 10,
        left: "center",
        textStyle: {
          color: "#fff"
        }
      }
    };

    // 合并props.data和自定义选项，确保series有效
    const finalOption = {
      ...baseOption,
      ...props.data,
      series:
        validSeries.length > 0 ? validSeries : [{ type: props.type, data: [] }],
      ...(props.option || {})
    };

    // 设置图表选项
    chartInstance.value.setOption(finalOption, true);

    // 如果设置了loading，显示loading效果
    if (props.loading) {
      chartInstance.value.showLoading();
    } else {
      chartInstance.value.hideLoading();
    }
  } catch (error) {
    console.error("ECharts配置错误:", error);
  }
};

// 监听主题变化
watch(
  () => isDark.value,
  () => {
    if (chartInstance.value) {
      chartInstance.value.dispose();
      initChart();
    }
  }
);

// 监听数据变化
watch(
  () => props.data,
  () => {
    nextTick(() => {
      updateChart();
    });
  },
  { deep: true }
);

// 监听选项变化
watch(
  () => props.option,
  () => {
    nextTick(() => {
      updateChart();
    });
  },
  { deep: true }
);

// 监听加载状态
watch(
  () => props.loading,
  val => {
    if (chartInstance.value) {
      val
        ? chartInstance.value.showLoading()
        : chartInstance.value.hideLoading();
    }
  }
);

// 监听DOM尺寸变化
watch(
  () => [props.width, props.height],
  () => {
    nextTick(() => {
      handleResize();
    });
  }
);

onMounted(() => {
  initChart();
});

onBeforeUnmount(() => {
  if (chartInstance.value) {
    window.removeEventListener("resize", handleResize);
    chartInstance.value.dispose();
    chartInstance.value = null;
  }
});
</script>

<template>
  <div ref="chartRef" :style="{ width, height }" class="re-chart" />
</template>

<style scoped>
.re-chart {
  width: 100%;
  height: 100%;
  min-height: 300px;
  transition: all 0.3s;
}
</style>
